/*MyPhotoIndex Free Photo Organizer <www.myphotoindex.com>
  Copyright (C) <2006-2010>  <Asaf Yarkoni asaf@yarkoni.net>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
using System;
using System.Collections.Generic;
using System.Text;
using MyPhotoIndex.Plugins.Share.pic4u.Properties;
using System.Drawing;
using System.Collections.ObjectModel;
using pic4uApi;
using System.Threading;
using System.IO;
using System.Drawing.Imaging;
using MyPhotoIndex.Utilities;
using System.Windows.Forms;
using MyPhotoIndex.Interfaces.Plugins;
using MyPhotoIndex.Interfaces;
using MyPhotoIndex.Interfaces.Imaging;
using MyPhotoIndex.Interfaces.ImageFormatProviders;
using MyPhotoIndex.Interfaces.Tagging;

namespace MyPhotoIndex.Plugins.Share.pic4u
{
    public class Pic4uPlugin : ISharePlugin
    {
        private IApplicationContext m_applicationContext;
        private System.Drawing.Size m_imageSize;
        private int m_progressValue;
        private Semaphore m_semaphore = new Semaphore(1, 1);

        private Authentication m_auth;

        #region ISharePlugin Members

        public System.Drawing.Image Icon
        {
            get { return Resources.logo; }
        }

        public void Send(ReadOnlyCollection<IImageData> imageFiles, Size imageSize)
        {
            m_imageSize = imageSize;

            m_applicationContext.ProcessProgress.IsInfinite = true;
            m_applicationContext.ProcessProgress.ProcessDescription = this.ToString();
            m_applicationContext.ProcessProgress.Running = true;

            try
            {
                if (m_auth == null)
                {
                    while (true)
                    {
                        string userName = Pic4uPluginSettings.Default.SavedUserName;
                        LoginForm loginForm = new LoginForm(userName);
                        DialogResult dr = loginForm.ShowDialog();
                        if (dr == DialogResult.Cancel)
                        {
                            m_applicationContext.ProcessProgress.Running = false;
                            return;
                        }

                        m_auth = new Authentication();
                        bool ok = m_auth.SignIn(loginForm.UserName, loginForm.Password);
                        if (ok == false)
                        {
                            m_auth = null;
                        }
                        else
                        {
                            Pic4uPluginSettings.Default.SavedUserName = loginForm.UserName;
                            Pic4uPluginSettings.Default.Save();
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
                m_applicationContext.ProcessProgress.Running = false;
                return;
            }

            m_applicationContext.ProcessProgress.Running = false;

            ThreadPool.QueueUserWorkItem(new WaitCallback(SendAsync), imageFiles);
        }

        private Dictionary<string, string> PrepareFilesForUpload(ReadOnlyCollection<IImageData> imageFiles)
        {
            Dictionary<string, string> files = new Dictionary<string, string>();
            foreach (IImageData imageData in imageFiles)
            {
                string tempFile = Path.GetRandomFileName();
                tempFile = Path.ChangeExtension(tempFile, "Jpg");
                tempFile = Path.Combine(Path.GetTempPath(), tempFile);

                using (Image image = imageData.FormatProvider.LoadImage(imageData, m_imageSize))
                {
                    IImageFormatProvider jpgProvider = ImageFormatProviders.ImageFormatProviders.Default["jpg"];
                    jpgProvider.SaveImage(image, imageData, tempFile);

                    files.Add(imageData.FileName, tempFile);
                }
            }

            return files;
        }

        public void SendAsync(Object state)
        {
            m_applicationContext.ProcessProgress.Running = true;

            ReadOnlyCollection<IImageData> imageFiles = state as ReadOnlyCollection<IImageData>;

            ImageUploader uploader = new ImageUploader(m_auth);
            uploader.ImageUploadEvent += new EventHandler<pic4uApi.ProgressEventArgs>(uploader_ImageUploadEvent);

            Dictionary<string, string> files = PrepareFilesForUpload(imageFiles);

            int totalSize = 0;
            foreach (string file in files.Values)
            {
                FileInfo fi = new FileInfo(file);
                totalSize += (int)fi.Length;
            }

            m_applicationContext.ProcessProgress.Running = false;

            m_progressValue = 0;
            m_applicationContext.ProcessProgress.Maximum = totalSize;
            m_applicationContext.ProcessProgress.IsInfinite = false;
            m_applicationContext.ProcessProgress.Running = true;

            foreach (IImageData imageData in imageFiles)
            {
                m_semaphore.WaitOne();
                m_applicationContext.ProcessProgress.ProcessDescription = this.ToString() + " - " + Path.GetFileName(imageData.FileName);
                SendOneImage(uploader, imageData, files[imageData.FileName]);
            }

            m_applicationContext.ProcessProgress.Running = false;

        }

        void SendOneImage(ImageUploader uploader, IImageData imageData, string fileName)
        {
            try
            {
                string description = imageData.Comment;
                string tags = string.Empty;

                foreach (int tagId in imageData.Tags)
                {
                    IImageTag imageTag = m_applicationContext.ImageTagCollection.GetTag(tagId);
                    if (imageTag != null)
                    {
                        tags += String.Format("\"{0}\",", imageTag.Name);
                    }
                }

                uploader.UploadOneImage(fileName, Path.ChangeExtension(imageData.FileName, "jpg"), 
                    description, tags, 
                    Pic4uPluginSettings.Default.IsPublic,
                    Pic4uPluginSettings.Default.IsFamily, 
                    Pic4uPluginSettings.Default.IsFriend);

                File.Delete(fileName);
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }
            finally
            {
                m_semaphore.Release();
            }
        }

        void uploader_ImageUploadEvent(object sender, pic4uApi.ProgressEventArgs e)
        {
            m_progressValue += e.Value;
            m_applicationContext.ProcessProgress.Value = m_progressValue;
            Application.DoEvents();
        }

        #endregion

        #region IPlugin Members

        public string Description
        {
            get { return "pic4u plugin"; }
        }

        public bool Load(IApplicationContext applicationContext)
        {
            m_applicationContext = applicationContext;
            Pic4uPluginSettings.SettingsManager = m_applicationContext.SettingsManager;
            Pic4uPluginSettings settings = Pic4uPluginSettings.Default;

            return true;
        }

        public string Name
        {
            get { return "pic4u plugin"; }
        }

        public void Unload()
        {
            
        }

        public override string ToString()
        {
            return "pic4u.co.il";
        }

        #endregion
    }
}
